package top.healthylife.gateway.feignapi;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.basics.utils.utils.R;
import top.healthylife.gateway.dto.request.result.ApiResultDto;
import top.healthylife.gateway.feignapi.dto.ApiPriceDto;
import top.heathylife.gateway.common.po.*;

import java.util.List;
import java.util.Map;

/**
 * @author maoxiaomeng
 */
@FeignClient("dynamic-api-gateway")
@SuppressWarnings("all")
public interface InterfaceApi {

    /**
     * 获取指定服务商的所有接口列表
     *
     * @param shortName 简称
     */
    @GetMapping("/interfaces/{shortName}")
    R<List<ParentApiPo>> getInterfaces(@PathVariable String shortName);


    /**
     * 获取指定服务商的所有信息
     *
     * @param shortName 简称
     * @return com.basics.utils.R<SystemPo>
     */
    @ApiOperation("获取指定服务商的所有信息")
    @GetMapping("/systemInfo/{shortName}")
    R<SystemPo> getSystemInfo(@PathVariable String shortName);

    /**
     * 获取指定接口的参数列表
     *
     * @param apiName   接口名称
     * @param shortName 简称
     */
    @GetMapping("/interfaces/{shortName}/{apiName}")
    R<List<ApiParameterPo>> getInterfaces(@PathVariable String shortName, @PathVariable String apiName);

    /**
     * 数据网关-统一接口调用入口
     * <p>periodValidity 为 null  则 适用 数据源默认配置的三方接口更新时间,如果当前调用的三方接口没有默认配置的更新时间,则取3600秒 即1h</p>
     * <p>不为null时,规则如下:</p>
     * <li> periodValidity<=0 :永不走缓存;
     * <li> periodValidity=0 :必定走缓存;
     * <li> periodValidity>0 :指定时间内走缓存;
     * <pre>如:periodValidity =5,则5秒内如果存在相同参数且调用没有异常的记录,则走缓存,如果没有符合条件的记录,将发起接口调用
     *
     *
     * @param shortName      系统简称
     * @param apiName        接口的名称
     * @param data           请求的数据
     * @param periodValidity 有效时间
     * @param secret         请求头服务中使用哪一个帐号和密码，如果没有填写帐号和密码的时候就没有这个权限，每一个secret都可对应多个不同的接口和服务
     * @return: com.basics.utils.R<java.lang.Object>
     */
    @PostMapping("/results/{shortName}/{apiName}")
    R<?> results(@PathVariable String shortName,
                 @PathVariable String apiName,
                 @RequestBody Map<String, Object> data,
                 @RequestHeader("secret") String secret,
                 @RequestHeader(value = "periodValidity", required = false) Long periodValidity);

    /**
     * 只用做调试使用
     * 获取缓存中的一条数据,如果缓存中有数据，获取最新的一条进行返回，否则不返回结果，
     *
     * @param shortName 系统简称
     * @param apiName   API接口名称
     * @author maoxiaomeng
     * @date: 2020/3/27 10:54
     * @return: com.basics.utils.R
     */
    @PostMapping("/cache/{shortName}/{apiName}")
    R<? extends ApiResultDto> cache(@PathVariable String shortName, @PathVariable String apiName);

    /**
     * 判断帐号是否在平台已经配置,如果帐号有异常则直接报错
     *
     * @param secret 秘钥
     * @return 如果帐号有异常则直接报错
     */
    @GetMapping("/check")
    R<?> check(@RequestHeader("secret") String secret) throws BusinessException;

    /**
     * 获取服务的系统参数解释
     *
     * @param shortName 系统简称
     * @author maoxiaomeng
     * @date: 2020/3/27 10:54
     * @return: com.basics.utils.R
     */
    @PostMapping("/index/{shortName}")
    R<?> index(@PathVariable String shortName);

    /**
     * 获取某个接口的出参入参
     *
     * @param apiName   接口名称
     * @param shortName 服务商简称
     * @return: com.basics.utils.R
     */
    @GetMapping("/api/params")
    R<?> apiParams(@RequestParam String apiName, @RequestParam String shortName);

    /**
     * 根据接口名模糊检索API,附带出参
     *
     * @param shortName 服务简称
     * @param keyword   搜索关键字
     * @return 返回包含指定参数的接口列表
     */
    @GetMapping("/search")
    R<List<ApiPriceDto>> search(@RequestParam String shortName, @RequestParam String keyword);

    /**
     * 根据接口名，服务名，获取入参对象
     *
     * @param shortName 服务简称
     * @param apiName   API名称
     * @return 返回类型为 Class<? extends ApiReqDto>
     */
    @GetMapping("/cls")
    R<String> getCls(@RequestParam String shortName, @RequestParam String apiName);


    /**
     * 根据接口名，服务名，获取接口对应的入参，出参的class路径名对象
     *
     * @param shortName 服务简称
     * @param apiName   API名称
     * @return 返回类型为 list.get(0)入参  list.gt(1)出参  使用Class.forName(String className)初始化对象
     */
    @GetMapping("/api/cls")
    R<List<String>> getClasses(@RequestParam String shortName, @RequestParam String apiName);


    /**
     * 通过三方数据商来校验账号是否可用
     *
     * @param shortName 服务商简称
     * @param secret    账号唯一标识 UUID
     * @param jsonMap   账号
     * @return 校验不通过直接抛出异常
     */
    @ApiOperation("校验账号是否可用")
    @PostMapping("/check/enable/{shortName}/{secret}")
    R<Boolean> checkEnable(@PathVariable String shortName, @PathVariable String secret, @RequestBody Map jsonMap);

    /**
     * 查询数据网关日志
     *
     * <ul>
     *     <li>id查询</li>
     *     <li>接口名称查询(=)</li>
     *     <li>数据源简称(=)</li>
     *     <li>调用方名称(=)</li>
     *     <li>开始时间-结束时间 区间查询</li>
     *     <li>是否查看缓存(=)</li>
     *     <li>秘钥查询(=)</li>
     *     <li>入参查询(like)</li>
     *     <li>流水号查询(=)</li>
     * </ul>
     *
     * @return
     */
    @ApiOperation("数据网关日志分页查询")
    @PostMapping("/log/page")
    R<Page<GatewayLogPo>> getGatewayLogByPage(@RequestBody GatewayLogByPage gatewayLogDto);
}
